#ifndef __TOYM__NET__EVENT_LOOP_H__
#define __TOYM__NET__EVENT_LOOP_H__

#include <memory>
#include <deque>
#include <mutex>
#include <sys/types.h>
#include "Base/noncopyable.h"
#include "net/Channel.h"
#include "net/TimerQueue.h"
#include "net/Callables.h"

namespace toym
{
namespace net
{

class IPoller;
class Channel;

class EventLoop: noncopyable {
public:
    EventLoop();
    ~EventLoop();

    bool isInLoopThread();
    void assertInLoopThread();
    void loop();
    void quit() {
        m_looping = false;
    }
    void updateChannel(Channel& channel);
    void removeChannel(Channel& channel);
    
    void runInLoop(const EventLoopFunctor_t& functor);
    void runInLoop(EventLoopFunctor_t&& functor);

    void runAt(Timestamp ts, const TimerCallback_t& cb);
    void runAt(Timestamp ts, TimerCallback_t&& cb);


    void enqueueLoop(const EventLoopFunctor_t& functor);
    void enqueueLoop(EventLoopFunctor_t&& functor);
private:
    void abortNotInLoopThread();
    void handleFunctors();

    std::unique_ptr<IPoller> m_poller;
    pid_t m_tid;
    
    Channel m_eventChannel;
    std::deque<EventLoopFunctor_t> m_functors;
    std::mutex m_functorMutex;

    TimerQueue m_timerQueue;

    bool m_looping;

    static thread_local EventLoop* loopInThisThread;
};

} // namespace net

} // namespace toym


#endif // __TOYM__NET__EVENT_LOOP_H__